﻿using System;
using System.Collections.Generic;
using System.Text;

namespace daBase.Objects.Safe
{
    /// <summary>
    /// Безопасный словарь
    /// </summary>
    /// <typeparam name="TKey">тип ключа</typeparam>
    /// <typeparam name="TValue">тип значения</typeparam>
    public class SafeDictionary<TKey, TValue>
    {
        // Содержимое словаря
        private Dictionary<TKey, TValue> content;

        // Если словарь пуст
        private IfNoMoreMethod<TValue, TKey> ifnomore;

        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="IfNoMore">метод, возвращающий новый экземпляр объекта типа TValue</param>
        public SafeDictionary(IfNoMoreMethod<TValue, TKey> IfNoMore)
        {
            content = new Dictionary<TKey, TValue>();
            ifnomore = IfNoMore;
        }

        /// <summary>
        /// Параметрический конструктор
        /// </summary>
        /// <param name="source">источник данных</param>
        /// <param name="IfNoMore">метод, возвращающий новый экземпляр объекта типа TValue</param>
        public SafeDictionary(IDictionary<TKey, TValue> Source, IfNoMoreMethod<TValue, TKey> IfNoMore)
        {
            content = new Dictionary<TKey, TValue>(Source);
            ifnomore = IfNoMore;
        }

        /// <summary>
        /// Параметрический конструктор
        /// </summary>
        /// <param name="source">источник данных</param>
        /// <param name="IfNoMore">метод, возвращающий новый экземпляр объекта типа TValue</param>
        public SafeDictionary(SafeDictionary<TKey, TValue> Source, IfNoMoreMethod<TValue, TKey> IfNoMore)
        {
            content = new Dictionary<TKey, TValue>(Source.content);
            ifnomore = IfNoMore;
        }

        /// <summary>
        /// Индексатор
        /// </summary>
        /// <param name="index">индекс</param>
        /// <returns>значение</returns>
        public TValue this[TKey index]
        {
            get
            {
                if (content.ContainsKey(index))
                    return content[index];
                return ifnomore(index);
            }
            set
            {
                if (content.ContainsKey(index))
                    content[index] = value;
                else content.Add(index, value);
            }
        }

        /// <summary>
        /// Содержит ли словарь заданный ключ
        /// </summary>
        /// <param name="key">ключ</param>
        /// <returns>содержит или нет</returns>
        public bool ContainsKey(TKey key)
        {
            return content.ContainsKey(key);
        }

        /// <summary>
        /// Очистка словаря
        /// </summary>
        public void Clear()
        {
            content.Clear();
        }
    }
}
